#include "QD3DTimeQuery.h"
#include "QD3DUtils.h"

QD3DTimeQuery::QD3DTimeQuery ()
{
	QD3DUtils d3DUtils;
	_pTimestampDisjointQuery = d3DUtils.createQuery (D3D11_QUERY_TIMESTAMP_DISJOINT);
	_pTimestampQuery = d3DUtils.createQuery (D3D11_QUERY_TIMESTAMP);
	_isExecuting = false;
	_isResultValid = false;
}

QD3DTimeQuery::~QD3DTimeQuery ()
{
	if (_pTimestampDisjointQuery) _pTimestampDisjointQuery->Release ();
	if (_pTimestampQuery) _pTimestampQuery->Release ();
}

void QD3DTimeQuery::begin ()
{
	_checkPointTimes.clear ();
	QD3DUtils ().beginDataCollection (_pTimestampDisjointQuery);
	_isExecuting = true;
}

void QD3DTimeQuery::end ()
{
	QD3DUtils d3DUtils;
	D3D11_QUERY_DATA_TIMESTAMP_DISJOINT timestampDisjointData;
	d3DUtils.endDataCollection (_pTimestampDisjointQuery);
	d3DUtils.getDataCollected (_pTimestampDisjointQuery,
			&timestampDisjointData,
			sizeof (D3D11_QUERY_DATA_TIMESTAMP_DISJOINT));
	_isResultValid = !timestampDisjointData.Disjoint;
	for (QMap< std::string, double >::iterator pointIter = _checkPointTimes.begin ();
			pointIter != _checkPointTimes.end (); ++pointIter)
		(*pointIter) /= timestampDisjointData.Frequency / 1000.0;
	_isExecuting = false;
}

void QD3DTimeQuery::addCheckPoint (std::string pointName)
{
	QD3DUtils d3DUtils;
	UINT64 timestamp;
	d3DUtils.endDataCollection (_pTimestampQuery);
	d3DUtils.getDataCollected (_pTimestampQuery, &timestamp,
			sizeof (UINT64));
	_checkPointTimes.insert (pointName, timestamp);
}

QMap< std::string, double > &QD3DTimeQuery::getCheckPointTimes ()
{
	return _checkPointTimes;
}

const QMap< std::string, double > &QD3DTimeQuery::getCheckPointTimes () const
{
	return _checkPointTimes;
}

double QD3DTimeQuery::getDuration (std::string startPoint, std::string endPoint) const
{
	return _checkPointTimes[endPoint] - _checkPointTimes[startPoint];
}

double QD3DTimeQuery::getTime (std::string point) const
{
	return _checkPointTimes[point];
}

int QD3DTimeQuery::getCheckPointSize () const
{
	return _checkPointTimes.size ();
}
